package com.hjx.movie.core.system.service.admin.impl;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hjx.movie.common.utils.ResultType;
import com.hjx.movie.common.utils.exceptions.CustomException;
import com.hjx.movie.core.system.runner.SystemStaticData;
import com.hjx.movie.core.system.service.admin.IMovieService;
import com.hjx.movie.core.system.vo.FileVo;
import com.hjx.movie.persistence.system.mapper.IvyMovieMapper;
import com.hjx.movie.persistence.system.model.IvyMovie;
import com.hjx.movie.persistence.system.model.IvySysStaticData;
import com.hjx.movie.persistence.system.model.IvyUser;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import javax.annotation.Resource;
import java.io.File;
import java.io.Serializable;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>Title:</p>
 * <p>Description:</p>
 *
 * @author hjx
 * @date 2021/1/31 - 17:04
 */
@Slf4j
@Service
@Transactional
@CacheConfig(cacheNames = "IvyMovie:SpringCache:MovieCache",keyGenerator = "cacheKeyGenerator")
public class MovieService extends ServiceImpl<IvyMovieMapper, IvyMovie> implements IMovieService {
    @Value("${file.disk}")
    private String disk;

    @Value("${file.path}")
    private String path;

    @Resource
    SystemStaticData staticData;

    public static final String MOVIE_TYPE_PREFIX = "MOVIE_TYPE_";
    public static final String MOVIE_AREA_PREFIX = "MOVIE_AREA_";
    private static final String MOVIE_PIC_PATH = "movie_pic";
    private static final String MOVIE_VIDEO_PATH = "movie_video";


    @Override
    public List<IvySysStaticData> findAllMovieType() {
        return staticData.getStaticDataList().stream()
                .filter(item->item.getParamKey().startsWith(MOVIE_TYPE_PREFIX))
                .collect(Collectors.toList());
    }

    @Override
    public List<IvySysStaticData> findAllMovieArea() {
        return staticData.getStaticDataList().stream()
                .filter(item->item.getParamKey().startsWith(MOVIE_AREA_PREFIX))
                .collect(Collectors.toList());
    }

    @Cacheable(unless = "#result==null")
    @Override
    public List<IvyMovie> findAllMovie() {
        return list();
    }

    @Cacheable(unless = "#result==null")
    @Override
    public List<IvyMovie> findAllMovieWrapper(Wrapper<IvyMovie> wrapper) {
        return list(wrapper);
    }

    @Cacheable(unless = "#result==null")
    @Override
    public IvyMovie findMovieById(Long id) {
        return getById(id);
    }

    @Cacheable(unless = "#result==null")
    @Override
    public List<IvyMovie> findMovieByIds(Collection<Long> ids) {
        return listByIds(ids);
    }

    @Cacheable(unless = "#result==null")
    @Override
    public List<IvyMovie> findMovieByIdsFor(Collection<Long> ids) {
        List<IvyMovie> list = new ArrayList<>();
        for (Long id:ids){
            list.add(findMovieById(id));
        }
        return list;
    }


    @CacheEvict(value = "IvyMovie:SpringCache:MovieCache",allEntries=true,beforeInvocation = true)
    @Override
    public boolean addMovie(IvyMovie movie) {
        return save(movie);
    }

    @CacheEvict(value = "IvyMovie:SpringCache:MovieCache",allEntries=true,beforeInvocation = true)
    @Override
    public boolean deleteMovie(Long movieId) {
        Assert.notNull(movieId,"删除电影的主键不能为空");
        return removeById(movieId);
    }

    @CacheEvict(value = "IvyMovie:SpringCache:MovieCache",allEntries=true,beforeInvocation = true)
    @Override
    public boolean updateMovie(IvyMovie movie) {
        Assert.notNull(movie.getMovieId(),"修改电影的主键不能为空");
        return updateById(movie);
    }

    @Override
    public String getMovieResHttpBaseUrl(String type){
        String baseUrl = "";
        if (StringUtils.isNotBlank(type)&&type.equals("img")){
            baseUrl = staticData.getStaticValue("BASE_URL_MOVIE_PIC");
        }else if (StringUtils.isNotBlank(type)&&type.equals("video")){
            baseUrl = staticData.getStaticValue("BASE_URL_MOVIE_VIDEO");
        }
        return baseUrl;
    }

    @Override
    public IPage<IvyMovie> findAllByPage(Page<IvyMovie> page,String type) {
        log.debug(type);
        LambdaQueryWrapper<IvyMovie> wrapper = new LambdaQueryWrapper<>();
        if (StringUtils.isNotBlank(type)&&staticData.getStaticValue("MOVIE_NOW_PLAY").equals(type)){
            wrapper.le(IvyMovie::getShowTime, LocalDateTime.now());
        }else if (StringUtils.isNotBlank(type)&&staticData.getStaticValue("MOVIE_FUTURE_PLAY").equals(type)){
            wrapper.ge(IvyMovie::getShowTime, LocalDateTime.now());
        }else {
            return page(page);
        }
        return page(page,wrapper);
    }

    @Override
    public List<FileVo> getMovieResFileList(Long movieId, String realPath,String type){
        String baseUrl = getMovieResHttpBaseUrl(type);
        File file = new File(realPath);
        List<FileVo> fileVoList = new ArrayList<>();
        String[] fileList = file.list();
        if (fileList==null||fileList.length==0){
            return fileVoList;
        }
        int i = 0;
        for (String name:fileList){
            i--;
            String url = baseUrl+movieId+"/"+name;
            FileVo fileVo = new FileVo(i,name,"done",url,url);
            fileVoList.add(fileVo);
        }
        return fileVoList;
    }

    @Override
    public boolean deleteMovieRes(String fileName, String realPath) {
        try {
            File file = new File(realPath+File.separator+fileName);
            return file.delete();
        }catch (Exception e){
            e.printStackTrace();
            return false;
        }
    }

    public String getRealPath(Long id,String type){
        String realPath = "";
        if (StringUtils.isNotBlank(type)&&type.equals("img")){
            realPath = disk+File.separator+path+File.separator+ MOVIE_PIC_PATH +File.separator+id;
        }else if (StringUtils.isNotBlank(type)&&type.equals("video")){
            realPath = disk+File.separator+path+File.separator+ MOVIE_VIDEO_PATH +File.separator+id;
        }else {
            throw new CustomException(ResultType.USER_INPUT_ERROR,"入参类型不正确");
        }
        return realPath;
    }

    @Override
    public List<IvyMovie> queryMovieLike(String s) {
        return lambdaQuery().like(IvyMovie::getMovieId,s)
                .or().like(IvyMovie::getMovieName,s)
                .list();
    }
}
